Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Raw β€’ View rendered β€’ Download

feature/docs/README.md bd2863243bab6eb213401d949839a2bc74dde7e2 (bd286324) Text, 6.49 KB

Tc9d1d9# `:feature:docs`

Tc9d1d9## Overview

The Ta5d6ff`:feature:docs` module is an **in-app documentation browser** with Compose Multiplatform UI. It bundles the Meshtastic user guide and developer guide as Compose resources at build time, provides full-text keyword search, Crowdin-backed multilingual content, optional ML Kit runtime translation (Google Play flavor), and a "Chirpy" AI Q&A assistant (Gemini Nano on Google Play; keyword fallback on F-Droid / Desktop / iOS).

**Targets:** Android Β· JVM (Desktop) Β· iOS (via Ta5d6ff`meshtastic.kmp.feature` convention plugin)

Tc9d1d9## Key Responsibilities

Tff7b72- Bundle Ta5d6ff`docs/en/user/**/*.md` and Ta5d6ff`docs/en/developer/**/*.md` as Compose resources at build time
Tff7b72- Sync Crowdin-translated locales into Ta5d6ff`composeResources/files/{locale}/docs/`
Tff7b72- Keyword search (TF-IDF style) across the full doc bundle
Tff7b72- Locale-aware content loading with Crowdin β†’ ML Kit fallback chain
Tff7b72- Adaptive list/detail layout (single pane on phones, split pane on tablets/desktop)
Tff7b72- Chirpy AI assistant: streaming Q&A against in-app docs via Gemini Nano or keyword fallback

Tc9d1d9## Source Structure

Ta5d6ff```
src/commonMain/kotlin/org/meshtastic/feature/docs/
β”œβ”€β”€ ai/
β”‚ β”œβ”€β”€ AIDocAssistant.kt ← interface (Gemini Nano / keyword fallback)
β”‚ β”œβ”€β”€ ChirpySessionHolder.kt
β”‚ └── KeywordFallbackAssistant.kt
β”œβ”€β”€ data/
β”‚ β”œβ”€β”€ DocBundleLoader.kt ← interface + DefaultDocBundleLoader
β”‚ └── KeywordSearchEngine.kt ← TF-IDF keyword search
β”œβ”€β”€ di/
β”‚ └── FeatureDocsModule.kt ← Koin module
β”œβ”€β”€ model/
β”‚ └── DocModels.kt ← DocSection, DocPage, DocBundle, DocSearchResult, ...
β”œβ”€β”€ navigation/
β”‚ └── DocsNavigation.kt ← docsEntries(), ChirpyUiState, rememberChirpyState()
β”œβ”€β”€ translation/
β”‚ β”œβ”€β”€ DocTranslationService.kt ← ML Kit (Google) or no-op (fdroid/desktop/iOS)
β”‚ β”œβ”€β”€ DocTranslationCache.kt
β”‚ β”œβ”€β”€ MarkdownTranslationSegmenter.kt
β”‚ └── NoOpDocTranslator.kt
└── ui/
β”œβ”€β”€ DocsBrowserScreen.kt ← list pane
β”œβ”€β”€ DocsPageRouteScreen.kt ← detail pane
β”œβ”€β”€ DocsSearchBar.kt
β”œβ”€β”€ ChirpyAssistantSheet.kt ← AI assistant bottom sheet
β”œβ”€β”€ ChirpyFab.kt ← floating action button that opens Chirpy
β”œβ”€β”€ ComposeResourceImageTransformer.kt
β”œβ”€β”€ DocPageIconResolver.kt
└── DocsPreviews.kt
```

Tc9d1d9## Key Types

Tc9d1d9### `DocSection` (sealed interface)

Ta5d6ff```Ta5d6ffkotlin
Tff7b72sealed Tff7b72interface T56d364DocSection Tb4b4b4{
Tff7b72data Tff7b72object T56d364UserGuide Tb4b4b4: Te6edf3DocSection
Tff7b72data Tff7b72object T56d364DeveloperGuide Tb4b4b4: Te6edf3DocSection
Tb4b4b4}
Ta5d6ff```

Tc9d1d9### `DocPage`

Ta5d6ff```Ta5d6ffkotlin
Tff7b72data Tff7b72class T56d364DocPageTb4b4b4(
Tff7b72val Te6edf3idTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3titleTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3sectionTb4b4b4: Te6edf3DocSectionTb4b4b4,
Tff7b72val Te6edf3navOrderTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3resourcePathTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3keywordsTb4b4b4: Te6edf3ListTff7b72<Tffa657StringTff7b72>Tb4b4b4,
Tff7b72val Te6edf3charCountTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4)
Ta5d6ff```

Tc9d1d9### `AIDocAssistant` (interface)

Ta5d6ff```Ta5d6ffkotlin
Tff7b72interface T56d364AIDocAssistant Tb4b4b4{
Tff7b72suspend Tff7b72fun Td2a8ffisSupportedTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Boolean
Tff7b72val Te6edf3modelStatusTb4b4b4: Te6edf3StateFlowTff7b72<Te6edf3ModelReadinessTff7b72>
Tff7b72suspend Tff7b72fun Td2a8ffanswerTb4b4b4(Te6edf3questionTb4b4b4: Tffa657StringTb4b4b4, Te6edf3currentPageIdTb4b4b4: Tffa657String? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Te6edf3AIDocAssistantResult
Tff7b72fun Td2a8ffanswerStreamTb4b4b4(Te6edf3questionTb4b4b4: Tffa657StringTb4b4b4, Te6edf3currentPageIdTb4b4b4: Tffa657String? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Te6edf3FlowTff7b72<Te6edf3AIDocAssistantResultTff7b72>
Tff7b72fun Td2a8ffresetSessionTb4b4b4(Tb4b4b4)
Tb4b4b4}
Ta5d6ff```

Ta5d6ff`AIDocAssistantResult` is a sealed interface: Ta5d6ff`Partial`, Ta5d6ff`Success`, Ta5d6ff`Fallback`, Ta5d6ff`Error`.

Platform bindings:
Tff7b72- **Google flavor**: Gemini Nano via on-device ML
Tff7b72- **F-Droid / Desktop / iOS**: Ta5d6ff`KeywordFallbackAssistant` (keyword search + summarisation, no network)

Tc9d1d9### `ChirpyMessage`

Ta5d6ff```Ta5d6ffkotlin
Tf0883e@Serializable
Tff7b72data Tff7b72class T56d364ChirpyMessageTb4b4b4(
Tff7b72val Te6edf3idTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3roleTb4b4b4: Te6edf3ChirpyRoleTb4b4b4, T8b949e// USER | ASSISTANT | SYSTEM
Tff7b72val Te6edf3textTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3sourcesTb4b4b4: Te6edf3ListTff7b72<Te6edf3SourceRefTff7b72>Tb4b4b4,
Tb4b4b4)
Ta5d6ff```

Tc9d1d9## Gradle Tasks

Two custom tasks keep bundled docs in sync:

| Task | Description |
|---|---|
| Ta5d6ff`syncDocsToComposeResources` | Copies Ta5d6ff`docs/en/user/**/*.md` and Ta5d6ff`docs/en/developer/**/*.md` into Ta5d6ff`src/commonMain/composeResources/files/docs/`, plus Ta5d6ff`docs/assets/screenshots/**/*.png` into Ta5d6ff`.../files/docs/assets/screenshots/`. Runs automatically before resource generation. |
| Ta5d6ff`syncTranslatedDocsToComposeResources` | Copies Crowdin-translated locales from Ta5d6ff`docs/{locale}/user/**/*.md` into Ta5d6ff`src/commonMain/composeResources/files/{locale}/docs/` using CMP qualifier format (e.g. Ta5d6ff`pt-rBR`). |

These tasks run automatically β€” no manual invocation is required during normal development.

Tc9d1d9## Navigation

Routes (registered under the Settings nav graph):

| Route | Description |
|---|---|
| Ta5d6ff`SettingsRoute.HelpDocs` | Doc browser list pane |
| Ta5d6ff`SettingsRoute.HelpDocPage` | Individual doc page detail pane |

The Ta5d6ff`docsEntries()` extension uses Material3 adaptive Ta5d6ff`ListDetailSceneStrategy` to automatically provide a split-pane layout on large screens.

Tc9d1d9## Dependency Graph

Tc9d1d9### Key Dependencies

Ta5d6ff```
feature:docs
β”œβ”€β”€ core:common, core:navigation, core:resources, core:ui, core:di
β”œβ”€β”€ coil (image loading in Markdown)
β”œβ”€β”€ markdown-renderer-m3 (Compose Markdown rendering)
β”œβ”€β”€ compose.material3.adaptive, compose.material3.adaptive.navigation3
└── kotlinx.collections.immutable
```

<!--region graph-->
Ta5d6ff```Ta5d6ffmermaid
Ta5d6ffgraph TB
:feature:docs[docs]:::kmp-feature
:feature:docs -.-> :core:common
:feature:docs -.-> :core:navigation
:feature:docs -.-> :core:resources
:feature:docs -.-> :core:ui
:feature:docs -.-> :core:di
:feature:docs -.-> :core:testing

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef compose-desktop-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-library-compose fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library-compose fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;

Ta5d6ff```
<!--endregion-->

Served by rngit 1.5.0 - Generated in 0.06s